// This file is used to generate static configurations for rotors, reflectors, and daily orders.
// reflectors are fully programmable, although I don't think this was implemented
// plugboards receive a random number of connections
// rotor output ring rotation is included in the daily orders
// rotor start positions refer to the output letter mapped to "A" on the input2
// rotors are generated separately, with notches cut into the output rings



//#![feature(vec_remove_item)]

use rand::{thread_rng, Rng};

//generate a set of alphabetical characters for an enigma cypher
pub fn rotorgen(config_dir:String) ->String{

    let mut basealph: Vec<u8> = Vec::new();
    let mut polyalph  = String::new();

    for i in 0..26 {
        basealph.push(i);
    } 
    let mut x = basealph.len();
    while basealph.len() > 0 {
        let out = (basealph.remove(thread_rng().gen_range(0,x)) +65)as char;
        polyalph.push(out);
        x -= 1;
    } 
    polyalph.push((thread_rng().gen_range(0,5) as u8) as char);
    polyalph
}

pub fn keygen(config_dir: String) -> String {
    println!("Generating daily keys:");
    let mut key = String::new();
// rotor order
    for _i in 0 .. 3 {
        key.push((thread_rng().gen_range(0,5) as u8) as char);
    }
    key.push_str("\n");
//ring settings
    for _i in 0 .. 3 {
        key.push((thread_rng().gen_range(0,26) as u8) as char);
    }
//start positions
    key.push_str("\n");
    for _i in 0 .. 3 {
        let p: u8 = thread_rng().gen_range(0,26) +65;

        key.push(p as char);
    }
//plugboard settings
    key.push_str("\n");
    let mut basealph: Vec<char> = Vec::new() ;
    for i in 0 .. 26 {
        basealph.push(((i +65) as u8) as char);
    }
    let mut j = basealph.len();
    for i in 0 .. 12 { //thread_rng().gen_range(0,13)*2 { // historical accuracy
        let k = thread_rng().gen_range(1,j)as usize;
        key.push(basealph[k]);
        basealph.remove(k);
        j -=1;
        if i %2 == 1 {
            key.push_str(" ");
        }
    }
//reflector settings, reflector is fully programmable
    key.push_str("\n");
    let mut basealph: Vec<char> = Vec::new() ;
    for i in 0 .. 26 {
        basealph.push(((i +65) as u8) as char);
    }
    let mut j = basealph.len();
    for i in 0 .. 26 {
        let k = thread_rng().gen_range(0,j)as usize;
        key.push(basealph[k]);
        basealph.remove(k);
        j -=1;
        if i %2 == 1 {
            key.push_str(" ");
        }
    }
    println!("{}", key);
    key
}
